import Obj3D from "../Poly/Obj3D.js";
import Geo from "../Poly/Geo.js";
import Mat from "../Poly/Mat.js";
import { Matrix4, Vector3 } from "three";

const defAttr = () => ({
  count: 0, //粒子的数量
  diff: [0, 0], //外扩长度, 飞行长度
  size: [15, 30], //粒子的大小区间
  color: [0, 1, 1, 0.5],
  program: "",
  gl: null,
});

//粒子 ba定向
export default class Particle {
  constructor(attr) {
    Object.assign(this, defAttr(), attr);
  }

  getElement(point) {
    return this._createParticle(point, this.count);
  }

  _createParticle(point, count) {
    let particle = new Obj3D();

    for (let i = 0; i < count; i++) {
      const config = this._createTriangleConfig(point);
      particle.add(this.gl, this._createTriangle(config));
    }
    return particle;
  }

  //创建三角形配制
  _createTriangleConfig(point) {
    const { size, color } = this;
    const angles = [Math.random() * 360, Math.random() * 70 * -1];
    const pointSize = [size[0], Math.random() * size[1] + size[0]];
    const posiArr = this._getNodePosi(point);

    const configTriangle = {
      a_Position: point,
      u_PosiMove: [posiArr[0].x, posiArr[0].y, posiArr[1].x, posiArr[1].y],
      u_Angle: angles,
      u_PointSize: pointSize,
      u_Opaque: [0.3, 0.5],
      u_Diff: 0.8,
      u_Color: color,
    };
    return configTriangle;
  }

  //计算开始点与结束点
  _getNodePosi(point) {
    const { diff } = this;

    const j = (Math.random() * 360 * Math.PI) / 180;
    //开始点
    let jcd_x = diff[0];
    let jcd_l = jcd_x * Math.cos(j);
    let jcd_d = jcd_x * Math.sin(j);
    let jcd = new Vector3(jcd_d, jcd_l, 0).add(point);
    //结束点
    let jsd_x = diff[0] + Math.random() * diff[1];
    let jsd_l = jsd_x * Math.cos(j);
    let jsd_d = jsd_x * Math.sin(j);
    let jsd = new Vector3(jsd_d, jsd_l, 0).add(point);

    return [jcd, jsd];
  }

  //创建三角形对象
  _createTriangle(config) {
    const {
      u_PointSize,
      u_Color,
      a_Position,
      u_PosiMove,
      u_Angle,
      u_Diff,
      u_Opaque,
    } = config;
    const { program } = this;
    return new Obj3D({
      depthTest: false,
      geo: new Geo({
        data: {
          a_Position: {
            size: 2,
            array: new Float32Array([a_Position.x, a_Position.y]),
          },
        },
      }),
      mat: new Mat({
        program: program,
        mode: ["POINTS"],
        data: {
          u_PointSize: { type: "uniform2fv", value: u_PointSize },
          u_Angle: { type: "uniform2fv", value: u_Angle },
          u_Opaque: { type: "uniform2fv", value: u_Opaque },
          u_Set: { type: "uniform1f", value: 0 },
          u_Diff: { type: "uniform1f", value: u_Diff },
          u_PosiMove: { type: "uniform4fv", value: u_PosiMove },
          u_Color: { type: "uniform4fv", value: u_Color },
        },
      }),
    });
  }
}
